home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tptc17sc.zip / TPCUNIT.INC < prev    next >
Text File  |  1988-03-26  |  13KB  |  606 lines

  1.  
  2. (*
  3.  * TPTC - Turbo Pascal to C translator
  4.  *
  5.  * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
  6.  *
  7.  *)
  8.  
  9.    
  10. (********************************************************************)
  11. (*
  12.  * process generic declaration section
  13.  *   dispatches to const, type, var, proc, func
  14.  *   enter with tok=section type
  15.  *   exit with tok=next section type
  16.  *
  17.  *)
  18.  
  19. procedure psection;
  20. begin
  21.    if recovery then
  22.    begin
  23.       while toktype <> keyword do
  24.          gettok;
  25.       {warning('Error recovery (psection)');}
  26.       recovery := false;
  27.    end;
  28.  
  29.    if debug_parse then write(' <section>');
  30.  
  31.    if (tok = 'EXTERNAL')  or (tok = 'OVERLAY') or
  32.       (tok = 'PROCEDURE') or (tok = 'FUNCTION') then
  33.       punit
  34.    else
  35.  
  36.    if tok = 'INTERFACE' then
  37.       pinterface
  38.    else
  39.    
  40.    if tok = 'IMPLEMENTATION' then
  41.       pimplementation
  42.    else
  43.    
  44.    if tok = 'USES' then
  45.    begin
  46.       puses;
  47.       if tok[1] = ';' then 
  48.          gettok;
  49.    end
  50.    else
  51.    
  52.    if tok = 'UNIT' then
  53.       comment_statement
  54.    else
  55.    
  56.    if tok = 'CONST' then
  57.       pconst
  58.    else
  59.  
  60.    if tok = 'TYPE' then
  61.       ptype
  62.    else
  63.  
  64.    if tok = 'VAR' then
  65.       pvar
  66.    else
  67.  
  68.    if tok = 'LABEL' then
  69.       plabel
  70.    else
  71.  
  72.    if tok[1] = '{' then
  73.       pblock
  74.    else
  75.  
  76.    if (tok[1] = '.') or (tok[1] = '}') then
  77.    begin
  78.       tok := '.';
  79.       exit;
  80.    end
  81.    else
  82.       syntax('Section header expected (psection)');
  83. end;
  84.  
  85.  
  86. (********************************************************************)
  87. (*
  88.  * process argument declarations to
  89.  *    program, procedure, function
  90.  *
  91.  * enter with header as tok
  92.  * exits with tok as ; or :
  93.  *
  94.  *)
  95.  
  96. const
  97.    extern = true;
  98.    
  99. procedure punitheader(is_external: boolean);
  100. var
  101.    proc:    string40;
  102.    proclit: string40;
  103.    vars:    paramlist;
  104.    types:   paramlist;
  105.    bases:   array [1..maxparam] of integer;
  106.    i:       integer;
  107.    ii:      integer;
  108.    rtype:   string40;
  109.    varval:  integer;
  110.    varon:   boolean;
  111.    locvar:  integer;
  112.    iptr:    integer;
  113.  
  114. begin
  115.    gettok;                 {skip unit type}
  116.    proclit := ltok;
  117.  
  118.    if (unitlevel > 1) and (not in_interface) then
  119.    begin
  120.       {make name unique if it clashes with an existing global}
  121.       if cursym = nil then
  122.          proc := proclit
  123.       else
  124.          proc := procnum + '_' + proclit;
  125.          
  126.       warning('Nested function');
  127.       
  128.       writeln(ofd[unitlevel-1],^M^J'   /* Nested function: ',proc,' */ ');
  129.       inc(objtotal,2);
  130.    end
  131.    else
  132.       proc := proclit;
  133.  
  134.    gettok;                 {skip unit identifier}
  135.  
  136.    vars.n := 0;
  137.    varval := 0;       { 0 bit means value, 1 = var }
  138.    varon  := false;
  139.  
  140.    (* process param list, if any *)
  141.    if tok[1] = '(' then
  142.    begin
  143.       gettok;
  144.  
  145.       while (tok[1] <> ')') and not recovery do
  146.       begin
  147.  
  148.          ii := vars.n + 1;
  149.          repeat
  150.             if tok[1] = ',' then
  151.                gettok;
  152.  
  153.             if tok = 'VAR' then
  154.             begin
  155.                gettok;
  156.                varon := true;
  157.             end;
  158.  
  159.             inc(vars.n);
  160.             if vars.n > maxparam then
  161.                fatal('Too many params (punitheader)');
  162.             vars.id[vars.n] := ltok;
  163.             gettok;
  164.  
  165.          until tok[1] <> ',';
  166.  
  167.          if tok[1] = ':' then       
  168.          begin
  169.             gettok;   {consume the :}
  170.    
  171.             {parse the param type}
  172.             rtype := psimpletype;
  173.          end
  174.          else
  175.  
  176.          begin    {untyped variable if ':' is missing}
  177.             rtype := 'void';
  178.             curtype := s_void;
  179.             curbase := 0;
  180.             cursuptype := ss_scalar; {ss_array?}
  181.          end;
  182.  
  183.          {assign and param types, converting 'var' and 'array' params}
  184.          iptr := 0;
  185.          if rtype[1] = '^' then
  186.             rtype[1] := '*';
  187.  
  188.          {flag var parameters; strings and arrays are implicitly var in C}
  189.          if varon and (curtype <> s_string) and (cursuptype <> ss_array) then
  190.             iptr := 1 shl (ii - 1);
  191.  
  192.          if curtype = s_string then
  193.             rtype := 'char *'
  194.          else
  195.          if cursuptype = ss_array then
  196.             rtype := typename[curtype] + ' *';
  197.  
  198.          {assign data types for each ident}
  199.          for i := ii to vars.n do   
  200.          begin
  201.             types.id[i] := rtype;
  202.             types.stype[i] := curtype;
  203.             types.sstype[i] := cursuptype;
  204.             bases[i] := curbase;
  205.             varval := varval or iptr;
  206.             iptr := iptr shl 1;
  207.          end;
  208.  
  209.          if tok[1] = ';' then
  210.          begin
  211.             gettok;
  212.             varon := false;
  213.          end;
  214.  
  215.       end;   {) seen}
  216.  
  217.       gettok;   {consume the )}
  218.    end;
  219.  
  220.    (* process function return type, if any *)
  221.    if tok[1] = ':' then
  222.    begin
  223.       gettok;            {consume the :}
  224.       rtype := psimpletype;
  225.  
  226.       if curtype = s_string then
  227.          rtype := 'char *'
  228.       else
  229.       if cursuptype = ss_array then
  230.          rtype := typename[curtype] + ' *';
  231.    end
  232.    else
  233.  
  234.    begin
  235.       rtype := 'void';
  236.       curtype := s_void;
  237.    end;
  238.  
  239.    putline;
  240.    
  241.    (* prefix procedure decl's when external *)
  242.    if is_external then
  243.    begin
  244.       putln(ljust('extern '+rtype,identlen)+proc+'();');
  245.       addsym(globals,proc,curtype,ss_func,0,varval,0,9,false);
  246.       exit;
  247.    end;
  248.  
  249.  
  250.    (* process 'as NEWNAME' clause, if present (tptc extention to specify
  251.       the replacement name in the symbol table *)
  252.    if tok = 'AS' then
  253.    begin
  254.       gettok;
  255.       proc := usetok;
  256.    end;
  257.     
  258.  
  259.    (* output the return type, proc name, formal param list *)
  260.    if in_interface then
  261.       rtype := 'extern '+rtype;
  262.    puts(ljust(rtype,identlen)+proc+'(');
  263.  
  264.    if vars.n = 0 then
  265.       puts('void');
  266.  
  267.  
  268.    (* output the formal param declarations *)
  269.    locvar := varval;
  270.    for i := 1 to vars.n do
  271.    begin
  272.       iptr := -1;
  273.  
  274.       if (locvar and 1) = 1 then
  275.       begin
  276.          iptr := -2;
  277.          types.id[i] := types.id[i] + ' *';
  278.       end;
  279.  
  280.       puts(ljust(types.id[i],identlen)+vars.id[i]);
  281.       addsym(locals,vars.id[i],types.stype[i],ss_scalar,iptr,0,0,bases[i],true);
  282.       locvar := locvar shr 1;
  283.  
  284.       if i < vars.n then
  285.       begin
  286.          putln(','); 
  287.          puts(ljust('',identlen+length(proc)+1));
  288.       end;
  289.    end;
  290.  
  291.    puts(')');
  292.    nospace := false;
  293.  
  294.    {enter the procedure in the global symbol table}
  295.    addsym(globals,proclit,curtype,ss_func,vars.n,varval,0,0,false);
  296.    cursym^.repid := proc;
  297. end;
  298.  
  299.  
  300. (********************************************************************)
  301. (*
  302.  * process body of program unit
  303.  *   handles all declaration sections
  304.  *   and a single begin...end
  305.  *   recursively handles procedure declarations
  306.  *   ends with tok=}
  307.  *)
  308.  
  309. procedure punitbody;
  310. begin
  311.    gettok;
  312.  
  313.    if tok = 'INTERRUPT' then
  314.    begin
  315.       warning('Interrupt handler');
  316.       gettok;
  317.    end;
  318.    
  319.    if tok = 'FORWARD' then
  320.    begin
  321.       puts(';');
  322.       gettok;
  323.    end
  324.    else
  325.  
  326.    if tok = 'EXTERNAL' then
  327.    begin
  328.       puts('/* ');
  329.       repeat
  330.          puttok;
  331.          gettok;
  332.       until tok[1] = ';';
  333.       puts(' */ ;');
  334.    end
  335.    else
  336.  
  337.    if tok = 'INLINE' then
  338.    begin
  339.       newline;
  340.       putln('{');
  341.       puts('   ');
  342.       pinline;
  343.       putln('}');
  344.    end
  345.    else
  346.  
  347.    begin
  348.       puts('{ ');
  349.  
  350.       repeat
  351.          if tok[1] = ';' then
  352.          begin
  353.             puttok;
  354.             gettok;
  355.          end;
  356.  
  357.          if tok[1] <> '{' then
  358.             psection;
  359.       until tok[1] = '{';
  360.  
  361.       gettok;                 {get first token of first statement}
  362.  
  363.       while (tok[1] <> '}') and not recovery do
  364.       begin
  365.          pstatement;             {process the statement}
  366.  
  367.          if tok[1] = ';' then
  368.          begin
  369.             puttok;
  370.             gettok;              {get first token of next statement}
  371.          end;
  372.       end;
  373.  
  374.       puttok;
  375.    end;
  376. end;
  377.  
  378.  
  379. (********************************************************************)
  380. procedure enter_procdef;
  381.    {increase output file level and di